package com.liuzhilong.util.easyimport.core;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.management.RuntimeErrorException;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.StringUtil;

import com.liuzhilong.util.easyimport.annotation.TargetColumn;
import com.liuzhilong.util.easyimport.annotation.TargetSheet;
import com.liuzhilong.util.easyimport.util.ConverseUtil;

 class ExcelMappingInner implements ExcelMapping{
	private Sheet sheet;
	private Class<?> targetBean;
	
	/**
	 * 字段名称和注解类的对照
	 */
	private Map<String,TargetColumn> beanFieldAnno;
	
	/**
	 * 列和属性的对照关系
	 * 列名为key value为属性
	 */
	
	private  Map<String,String> column2Field ;
	
	/**
	 * sheet中列的索引
	 */
	
	private  Map<String,Integer> columnIndex ;
	
	
	
	
	private TargetSheet targetSheet; 
	
	
	
	
	
	
	public ExcelMappingInner(Sheet sheet, Class<?> targetBean) {
		this.sheet =sheet;
		this.targetBean = targetBean;
		init();
	}
	
	private void init() {
		targetSheet = targetBean.getAnnotation(TargetSheet.class);

		if(beanFieldAnno==null) {
			beanFieldAnno = this.getBeanFieldAnno();
		}
		

		if(column2Field==null) {
			column2Field = this.getColumn2Field();
		}
		
		
		if(columnIndex==null) {
			columnIndex = this.getColumnIndex();
		}
		
		
		
	}
	
	

	public List<?> list() throws InstantiationException, IllegalAccessException, InvocationTargetException, ParseException {
		
		List result = new ArrayList();
		
		int allRowCount = this.sheet.getLastRowNum()+1;
		
		int dataRowIndex =this.targetSheet.dataStartRow();
		
		Set<String> colunmSet = this.columnIndex.keySet();
		if(colunmSet.size()==0) {
			throw new RuntimeException("no data found!");
		}
		//2018年9月1日14:47:04 刘志龙 增加过滤空行的功能
		for(int rowIndex=dataRowIndex;rowIndex<allRowCount;rowIndex++) {
			Row dataRow = this.sheet.getRow(rowIndex);
			Object reusltBean = this.targetBean.newInstance();
			boolean isNullRow = true;
			for(String columName:colunmSet) {

				Cell cell= dataRow.getCell(this.columnIndex.get(columName));
				if(cell == null){
					continue;
				}
				String cellValue =cell .getStringCellValue();
				if(cellValue==null||cellValue.equals("")){
					continue;
				}
				isNullRow = false;
				String fieldName = this.column2Field.get(columName);
				//时间类型特殊处理 其他类型交给BeanUtil处理
				Field field=null;
				try {
					field = reusltBean.getClass().getDeclaredField(fieldName);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					throw new RuntimeException(e.getMessage());
				}
				BeanUtils.setProperty(reusltBean, fieldName, ConverseUtil.converseData(cellValue, field));
			}
			if(isNullRow){
				continue;
			}
			result.add(reusltBean);
		}
		
		
		
		
		// TODO Auto-generated method stub
		return result;
	}
	
	
	
	
	
	
	/**
	 * 获取字段名称和注解类的对照
	 * 字段名称为Key
	 * @return
	 */
	
	private Map<String,TargetColumn> getBeanFieldAnno(){
		HashMap<String, TargetColumn> result = new HashMap<String, TargetColumn>();
		for(Field item:this.targetBean.getDeclaredFields()) {
			if(item.isAnnotationPresent(TargetColumn.class)) {
				TargetColumn column = item.getAnnotation(TargetColumn.class);
				String fieldName=item.getName();
				result.put(fieldName, column);
			}
		}
		return result;
	}
	
	
	/**
	 * 获得列名称和属性名称的对应
	 * @return
	 */
	
	private Map<String,String > getColumn2Field(){
		HashMap<String, String> reuslt = new HashMap<String, String>();
		for(String fieldName:this.beanFieldAnno.keySet()) {
			String colunmName = beanFieldAnno.get(fieldName).name();
			if(colunmName==null||"".equals(colunmName)) {
				colunmName = fieldName;
			}
			reuslt.put(colunmName, fieldName);
		}
		return reuslt;
	}
	
	
	
	
	/**
	 * 获取列名称和字段名称的对应
	 * 列名称为key 字段名称为value
	 * @return
	 */
	private Map<String,Integer> getColumnIndex(){
		HashMap<String, Integer> reuslt = new LinkedHashMap<String, Integer>();
		
		int rowCount = this.sheet.getPhysicalNumberOfRows();
		if(this.targetSheet.mappingRow()+1>=rowCount) {
			throw new RuntimeException("mapping row大于sheet的行数");
		}
		Row mappingRow = this.sheet.getRow(this.targetSheet.mappingRow());
		
		Set<String> colunmNameDelare = this.column2Field.keySet();
		
		int columnCount=  mappingRow.getPhysicalNumberOfCells();
		
		for(int cIndex=0;cIndex<columnCount;cIndex++) {
			Cell mappingCell = mappingRow.getCell(cIndex);
			String colunmName=mappingCell.getStringCellValue(); 
			if(colunmNameDelare.contains(colunmName)) {
				reuslt.put(colunmName, cIndex);
			} 
		}
		
		return reuslt;
	}
	
	
	
}
